Popular Searches
Popular Course Categories
Popular Courses

Understanding public, private, protected, and Default Access

Understanding public, private, protected, and Default Access

Access Modifiers, Static Members, and Final Keyword

Understanding public, private, protected, and Default Access Modifiers in Java

Course: Core Java Training

Topic: Understanding public, private, protected, and Default Access

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to Access Modifiers in Java

Access modifiers are keywords in Java that control the visibility and accessibility of classes, variables, methods, constructors, and nested classes. They help developers decide which parts of a program can be accessed by other classes and which parts should remain hidden.

Access control is an important part of object-oriented programming because it supports encapsulation, protects internal data, reduces unwanted dependencies, and makes applications easier to maintain.

Java provides four common access levels for class members: public, private, protected, and default (package-private). Each level defines a different boundary for accessing a member.

For example, a bank account's balance should generally not be modified directly by every class in an application. A private field and public methods such as deposit() and withdraw() can control how the balance changes.

2. Learning Objectives

  • Understand the purpose of access modifiers in Java.
  • Learn how public, private, protected, and default access work.
  • Understand accessibility within the same class and package.
  • Learn how protected access behaves with inheritance across packages.
  • Identify which modifiers can be used with top-level classes.
  • Apply access modifiers to fields, methods, constructors, and nested classes.
  • Understand encapsulation and data hiding through practical examples.
  • Prepare for common Core Java interview questions.

3. What Are the Four Access Levels?

Java access levels determine how widely a member can be accessed. From the most restrictive to the most accessible, the general order is private, default, protected, and public, although protected access has special rules for subclasses in different packages.

Access Level Keyword Accessibility
Private private Only within the declaring top-level class's body, including its nested code where Java permits access.
Default / Package-private No keyword Within the same package.
Protected protected Within the same package and through the applicable subclass access rules outside the package.
Public public Wherever the declaring type itself is accessible.

4. Understanding the public Access Modifier

The public access modifier provides the widest accessibility. A public class or member can be accessed from other classes and packages, provided the declaring type and any other required access conditions allow it.

Key Characteristics of public

  • Can be accessed from classes in the same package.
  • Can be accessed from classes in other packages when the declaring type is accessible.
  • Can be applied to fields, methods, constructors, and classes where permitted.
  • Is commonly used for methods that form part of a class's public API.
  • Should be used carefully because public members create dependencies for other code.

Example: Using public Methods

public class Student {
    public String name = "Rahul";

    public void displayName() {
        System.out.println("Student Name: " + name);
    }
}

The name field and displayName() method are public. Another accessible class can use them through a Student object.

Example: Accessing a Public Member

public class Main {
    public static void main(String[] args) {
        Student student = new Student();

        System.out.println(student.name);
        student.displayName();
    }
}

Output:

Rahul
Student Name: Rahul

When Should You Use public?

  • For methods intended to be used by other classes.
  • For constructors that should allow external object creation.
  • For public service classes that form part of an application's API.
  • For methods that expose controlled operations on an object.

Avoid making every field public. Public fields can allow other classes to change an object's state without validation.

5. Understanding the private Access Modifier

The private access modifier restricts access to the declaring top-level class. Other unrelated classes cannot directly access that private member, even if they are in the same package.

Private access is commonly used to hide implementation details and protect an object's internal state.

Key Characteristics of private

  • Provides the most restrictive member access level.
  • Can be used for fields, methods, constructors, and nested classes where permitted.
  • Helps implement encapsulation and data hiding.
  • Private members are not directly accessible by subclasses.
  • Other classes can interact with private state through suitable accessible methods or constructors.

Example: Private Field

public class Employee {
    private double salary = 45000;

    public void displaySalary() {
        System.out.println("Salary: " + salary);
    }
}

The salary field is private. It can be accessed directly within the Employee class, but unrelated classes cannot access it directly.

Incorrect Access Example

public class Main {
    public static void main(String[] args) {
        Employee employee = new Employee();

        // Compile-time error:
        // System.out.println(employee.salary);

        employee.displaySalary();
    }
}

Output:

Salary: 45000.0

The direct field access is commented out because it would cause a compilation error. The public method provides an accessible way to display the salary.

Using Private Fields with Getters and Setters

A getter reads a field's value, while a setter updates it. Setters can validate data before making a change.

public class BankAccount {
    private double balance;

    public BankAccount(double initialBalance) {
        if (initialBalance < 0) {
            throw new IllegalArgumentException(
                "Initial balance cannot be negative"
            );
        }
        balance = initialBalance;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        BankAccount account = new BankAccount(1000);
        account.deposit(500);

        System.out.println("Balance: " + account.getBalance());
    }
}

Output:

Balance: 1500.0

The private field prevents arbitrary direct changes from unrelated classes. The public methods define how the balance can be read and updated.

6. Understanding the Default Access Modifier

In Java, default access means that no explicit access modifier is written. This is also called package-private access. A member with default access can be used by classes in the same package but not by unrelated classes in other packages.

Default access is not represented by a keyword named default in an ordinary class field or method declaration. Writing default before an ordinary class method does not mean package-private access; the keyword has a different role for interface methods.

Key Characteristics of Default Access

  • No access modifier is written in the declaration.
  • Members are accessible to classes within the same package.
  • Members are not directly accessible to unrelated classes in other packages.
  • It is useful for implementation details shared within a package.
  • A top-level class without an access modifier also has package-private access.

Example: Default Access

class Calculator {
    int add(int a, int b) {
        return a + b;
    }
}

The Calculator class and its add() method have default access. Classes in the same package can access them.

Accessing Default Members in the Same Package

class Main {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        int result = calculator.add(10, 20);
        System.out.println("Sum: " + result);
    }
}

Output:

Sum: 30

This example works when both classes are in the same package. If Main is placed in another package, it cannot directly access the package-private Calculator class or its members.

When Should You Use Default Access?

  • When a class or method is intended only for use within a package.
  • When multiple classes in one package need to share implementation details.
  • When a method should not become part of a public API.
  • When package-level collaboration is appropriate for the design.

7. Understanding the protected Access Modifier

The protected access modifier allows access within the same package and also provides access to subclasses located in other packages, subject to Java's protected-access rules.

It is often useful when a base class provides behavior or state intended for specialized subclasses.

Key Characteristics of protected

  • Accessible within the declaring class.
  • Accessible to other classes in the same package.
  • Accessible to subclasses in other packages under the subclass access rules.
  • Can be used with fields, methods, and constructors.
  • Cannot be used to declare a top-level class or interface.

Example: Protected Method

class Animal {
    protected void makeSound() {
        System.out.println("Animal makes a sound.");
    }
}

class Dog extends Animal {
    public void bark() {
        makeSound();
        System.out.println("Dog barks.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.bark();
    }
}

Output:

Animal makes a sound.
Dog barks.

The Dog class inherits from Animal and can call the protected method as part of its subclass behavior.

Protected Access Across Packages

When a subclass is in another package, protected access is more restricted than simply allowing access through any object. The subclass can access the inherited protected member through its own inheritance context, but ordinary code cannot freely access that member through any arbitrary superclass instance.

For example, a subclass can call an inherited protected method with makeSound() from one of its instance methods. However, code in an unrelated class in another package cannot call that protected method directly.

8. Comparison of All Four Access Modifiers

Access Level Same Class Same Package Subclass in Another Package Unrelated Class in Another Package
private Yes No direct access No direct access No
Default (no modifier) Yes Yes No No
protected Yes Yes Yes, subject to subclass access rules No
public Yes Yes Yes, if the declaring type is accessible Yes, if the declaring type is accessible

Important: The table describes access to members. Actual accessibility also depends on whether the declaring class and its enclosing types are themselves accessible.

9. Access Modifiers for Classes

Access rules for top-level classes differ from the rules for class members. A top-level class or interface can be declared public or left without a modifier, making it package-private.

A top-level class cannot be declared private or protected. Those access levels can be used for nested classes, where permitted.

Example: Public Class

package college;

public class Student {
    public void display() {
        System.out.println("Student class is accessible.");
    }
}

Other packages can access the public Student class if the package is available and the class is accessible in the application or module.

Example: Package-Private Class

package college;

class Teacher {
    void teach() {
        System.out.println("Teacher is teaching.");
    }
}

The Teacher class can be accessed by other classes in the college package, but it cannot be directly imported and used from an unrelated package.

10. Access Modifiers for Variables

Fields store an object's state or class-level data. Choosing an appropriate access level helps prevent accidental changes and supports encapsulation.

Example

public class Product {
    public String name = "Laptop";
    private double price = 55000;
    protected int stock = 10;
    String category = "Electronics";

    public double getPrice() {
        return price;
    }
}

In this example:

  • name is public and can be accessed wherever the class is accessible.
  • price is private and can be accessed directly only within Product.
  • stock is protected and follows package and subclass access rules.
  • category has default access and is accessible within its package.

For most application fields, private access is a good starting point. Public methods can expose only the operations that other classes need.

11. Access Modifiers for Methods

Methods define the behavior of a class. Their access modifiers determine which code can call them.

public class UserService {
    public void registerUser() {
        validateUser();
        System.out.println("User registered.");
    }

    private void validateUser() {
        System.out.println("Validating user...");
    }

    protected void logActivity() {
        System.out.println("Activity logged.");
    }

    void resetCache() {
        System.out.println("Cache reset.");
    }
}

Here, registerUser() is public, validateUser() is private, logActivity() is protected, and resetCache() has default access.

Output when registerUser() is called:

Validating user...
User registered.

The public method can call the private helper because both belong to the same class. Other classes can call the public method without needing direct access to the validation logic.

12. Access Modifiers for Constructors

Constructors initialize objects. Their access levels determine where instances can be created directly.

  • Public constructor: Allows object creation wherever the class is accessible.
  • Private constructor: Restricts direct construction from outside the declaring class, often for utility classes or controlled instance creation.
  • Protected constructor: Allows construction within the package and through applicable subclass access rules.
  • Default constructor access: If a constructor is declared without an access modifier, it is package-private.

Example: Private Constructor

public class Utility {
    private Utility() {
        // Prevent direct object creation.
    }

    public static int square(int number) {
        return number * number;
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Utility.square(5));
    }
}

Output:

25

The private constructor prevents other classes from creating a Utility object directly. The public static method can be called without creating an object.

13. Access Modifiers and Encapsulation

Encapsulation means combining data and related methods within a class while controlling access to the object's internal state. Access modifiers are important tools for implementing encapsulation.

A common approach is to keep fields private and expose public methods that validate or manage changes.

Example: Student Marks

public class Student {
    private int marks;

    public void setMarks(int marks) {
        if (marks >= 0 && marks <= 100) {
            this.marks = marks;
        } else {
            System.out.println("Invalid marks.");
        }
    }

    public int getMarks() {
        return marks;
    }
}

public class Main {
    public static void main(String[] args) {
        Student student = new Student();

        student.setMarks(85);
        System.out.println("Marks: " + student.getMarks());

        student.setMarks(150);
    }
}

Output:

Marks: 85
Invalid marks.

The private marks field cannot be modified directly by unrelated classes. The setter ensures that only values within the allowed range are accepted.

14. Access Modifiers and Inheritance

Inheritance allows one class to extend another class. Access modifiers affect which inherited members a subclass can use.

  • public members are accessible to subclasses when the declaring type is accessible.
  • protected members are accessible to subclasses, including those in another package under the protected-access rules.
  • Default-access members are accessible to subclasses in the same package, but not to subclasses in another package merely because of inheritance.
  • private members cannot be accessed directly by subclasses, although the superclass's accessible methods may provide controlled access to them.

Example: Protected Inheritance

class Person {
    protected String name = "Aarav";

    protected void displayName() {
        System.out.println("Name: " + name);
    }
}

class Student extends Person {
    public void showDetails() {
        displayName();
    }
}

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        student.showDetails();
    }
}

Output:

Name: Aarav

The subclass can access the protected field and method through its inheritance relationship.

15. Common Mistakes to Avoid

  • Confusing default access with the default keyword: Package-private access is created by omitting a modifier.
  • Declaring a top-level class private or protected: These access levels are not permitted for top-level classes.
  • Accessing private fields directly: Use an appropriate public or otherwise accessible method instead.
  • Assuming protected means public: Protected access outside the package is subject to subclass rules.
  • Assuming a public member is always accessible: The declaring class and enclosing types must also be accessible.
  • Making every member public: This exposes implementation details and increases coupling.
  • Using default access unintentionally: Omitting a modifier may prevent other packages from accessing a member.
  • Ignoring package declarations: Package placement affects default and protected access.

16. Best Practices for Using Access Modifiers

  • Prefer private fields to protect internal state.
  • Expose public methods only when they are part of the intended API.
  • Use protected members when subclasses genuinely need access to implementation details.
  • Use package-private access for collaboration limited to a single package.
  • Validate values before updating important object state.
  • Avoid exposing mutable internal collections or objects without a clear reason.
  • Keep helper methods private when they are used only inside one class.
  • Document public APIs and their expected behavior.
  • Choose the most restrictive access level that meets the design requirements.

17. Practice Exercises

  1. Create a Student class with a private field for marks and public getter and setter methods.
  2. Create a public Calculator class with a private helper method used by a public calculation method.
  3. Create two classes in the same package and demonstrate access to a default-access method.
  4. Create a superclass with a protected method and call it from a subclass.
  5. Try accessing a protected method from an unrelated class in another package and observe the compilation result.
  6. Create a utility class with a private constructor and a public static method.
  7. Write a short program demonstrating all four access levels and explain which accesses are valid.

18. Interview Questions and Answers

Q1. What are access modifiers in Java?

Access modifiers control the visibility of classes and class members, helping define which parts of a program can access particular declarations.

Q2. How many common access levels does Java provide?

Java provides four common access levels for members: public, protected, default (package-private), and private.

Q3. What is the public access modifier?

public allows access wherever the declaring type and other relevant access conditions permit it.

Q4. What is the private access modifier?

private restricts direct access to the declaring top-level class's body, including access allowed to its nested code.

Q5. What is default access in Java?

Default or package-private access applies when no access modifier is specified. The member can be accessed within its package.

Q6. What is the protected access modifier?

protected allows access within the same package and through subclass access rules outside the package.

Q7. Can a top-level class be private?

No. A top-level class can be public or package-private. Private and protected access can be used for nested classes where permitted.

Q8. Can a subclass access private members of its superclass directly?

No. A subclass cannot directly access its superclass's private members, but it may use accessible superclass methods that operate on those members.

Q9. What is the difference between default and protected access?

Default access is limited to the same package. Protected access also permits certain accesses from subclasses in other packages.

Q10. Which access modifier is best for fields?

Private is a good default choice for fields because it protects internal state and allows controlled access through methods.

Q11. Can a constructor be private?

Yes. A private constructor restricts direct construction from outside the declaring class and is often used in utility classes or controlled object-creation patterns.

Q12. Why are access modifiers important in encapsulation?

They help hide implementation details, control access to data, prevent invalid changes, and define a clear boundary between a class and its users.

19. Quick Revision Checklist

  • public: accessible wherever the declaring type is accessible.
  • private: direct access restricted to the declaring top-level class and permitted nested code.
  • Default access: no modifier; accessible within the same package.
  • protected: accessible within the package and through subclass rules outside the package.
  • Top-level classes can be public or package-private.
  • Private fields support encapsulation and controlled access.
  • Access modifiers can be applied to fields, methods, constructors, and nested types where permitted.
  • Package declarations affect access rules.
  • Prefer the most restrictive access level that meets the design requirements.

20. Conclusion

Understanding public, private, protected, and default access is essential for writing secure, maintainable, and well-structured Java applications. Each access level serves a different purpose: public exposes functionality, private hides internal details, default supports package-level collaboration, and protected supports package access and inheritance.

By selecting access modifiers carefully, developers can implement encapsulation, reduce unwanted dependencies, and design classes with clear responsibilities. Practicing these concepts with multiple classes and packages will strengthen your Core Java and object-oriented programming skills.


Learn More with JustAcademy

Explore the Core Java Training Course to strengthen your understanding of Java fundamentals, object-oriented programming, and access control.

Register for a Course Demo to learn more about the training program.

Visit the JustAcademy website to explore additional courses and learning resources.

Previous Next
whatsapp